from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import (
    UserCreationForm,
    PasswordResetForm,
    AuthenticationForm,
)
from django.utils.safestring import mark_safe

from .models import Profile

User = get_user_model()


class CustomPasswordResetForm(PasswordResetForm):
    """定制密码重置表单，确保用户提交的邮箱是已经注册过的，并且该账户是激活的"""

    def clean_email(self):
        email = self.cleaned_data.get('email')
        # 调用父类的get_users方法，返回生成器对象
        users = self.get_users(email)
        try:
            next(users)
        except StopIteration:
            raise forms.ValidationError('该邮箱还未注册，请使用注册过的邮箱或注册该邮箱')
        else:
            return email


class RegistrationForm(UserCreationForm):
    """用户注册表单，包含邮箱地址，用户名，密码和确认密码输入框"""
    email = forms.EmailField(label='邮箱', required=True)

    class Meta(UserCreationForm.Meta):
        model = User  # 需要重新指定model为自定制用户，否则用户管理器(UserManager)查找错误
        fields = ('username', 'email')

    def __init__(self, *args, **kwargs):
        """重写init方法使得用户名输入框聚焦而不是邮箱输入框聚焦"""
        # forms.ModelForm.__init__(self, *args, **kwargs)
        super().__init__(*args, **kwargs)
        self.fields['username'].widget.attrs['autofocus'] = True

    def save(self, commit=True):
        """重写save方法使用用户注册完后为未激活状态"""
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])

        # 未激活状态
        user.is_active = False
        if commit:
            user.save()
        return user


class UserUpdateForm(forms.ModelForm):
    """用户更新基本信息表单"""
    email = forms.EmailField(label='邮箱')

    class Meta:
        model = User
        fields = ['username', 'email']

    def clean_username(self):
        """钩子函数，如果用户输入新的用户名且该用户名已经被别人使用则抛出异常，提醒用户"""
        username = self.cleaned_data.get('username')
        # self.instance获得当前的模型类对象
        if self.instance.username != username and User.objects.filter(username=username).exists():
            raise forms.ValidationError('该用户名已经被使用')
        return username

    def clean_email(self):
        """钩子函数，如果用户输入新的邮箱地址且该邮箱已经被别人使用则抛出异常，提醒用户"""
        email = self.cleaned_data.get('email')
        # self.instance获得当前的模型类对象
        if self.instance.email != email and User.objects.filter(email=email).exists():
            raise forms.ValidationError('该邮箱已经被使用')
        return email


class ProfileForm(forms.ModelForm):
    """个人中心表单"""

    class Meta:
        model = Profile
        fields = ['avatar']


class CustomAuthenticationForm(AuthenticationForm):
    """自定制认证表单实现登录验证码功能"""
    verify_code = forms.CharField(
        label='认证码',
        strip=True,
        error_messages={
            'required': '验证码不能为空'
        }
    )

    # 重写错误信息，如果用户未激活提示用户激活，提供激活链接
    error_messages = {
        'invalid_login': "请输入正确的用户名%(username)s和密码，注意大小写",
        'inactive': mark_safe(f'''该账户尚未激活,请<a href="#">激活</a>'''),
    }

    def clean_verify_code(self):
        """比较用户输入的认证码和session中保存的验证码，如果不一致返回错误信息，否则返回正确的验证码"""
        code = self.cleaned_data.get('verify_code')
        session_code = self.request.session.get('verify_code')
        if not all([code, session_code, code == session_code]):
            raise forms.ValidationError('认证码错误')
        return code

    # def confirm_login_allowed(self, user):
    #     return None
